#include "Player.h"

#include "SFML/Window/Keyboard.hpp"
#include "SFML/Window/Joystick.hpp"
#include "Bullet.h"


#include <iostream>
using namespace std;

Player::Player(GameState *gameState) : PhysicalObject(gameState)
{
	addProperty("player");

	getBodyDef()->type = b2_dynamicBody;
	getBodyDef()->fixedRotation = true;
	b2FixtureDef *fixDef = new b2FixtureDef;
	b2PolygonShape *shape = new b2PolygonShape;
	shape->SetAsBox(0.2f, 1.5f);
	fixDef->shape = shape;
	fixDef->density = 1.0;
	fixDef->restitution = 0.3f;
	addFixtureDef(fixDef);
	setRotation(0.0f);

	m_angle = 0.8f;
	m_force = 30.0f;
	m_state = 0;

	setColor(1.0f, 1.0f, 1.0f);

	TextureManager &tm = m_gameState->getTextureManager();
	m_sprite[0] = tm.getTexture("sm0.png");
	m_sprite[1] = tm.getTexture("sm1.png");
	m_sprite[2] = tm.getTexture("sm2.png");
	m_sprite[3] = tm.getTexture("sm3.png");
	m_sprite[4] = tm.getTexture("sm4.png");
	m_sprite[5] = tm.getTexture("sm5.png");
	m_sprite[6] = tm.getTexture("sm6.png");
	m_sprite[7] = tm.getTexture("sm7.png");

	m_frame = 0;
	m_runAnim = false;

  m_jumpPos = b2Vec2(-10.0, -5.0 /* getPosition().y */);
}


Player::~Player()
{
}


void Player::draw(){
	
	b2Vec2 position = getPosition();
	float rotation = m_body->GetAngle();
	b2Vec2 size = getSize();

	sf::Texture::bind(m_sprite[m_frame]);

	glColor4fv(m_color);
	glPushMatrix();
	{
		glTranslatef(position.x,position.y,0);
		glRotatef(rotation*57.2957795,0,0,1);
		glScalef(size.x, size.y, 1.0f);
		glBegin(GL_QUADS);
		{			
			glTexCoord2f(0.0f, 1.0f); glVertex3f( -0.5f, -0.5f,  0.0f);
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f, -0.5f,  0.0f);
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, 0.5f,  0.0f);
			glTexCoord2f(0.0f, 0.0f); glVertex3f( -0.5f, 0.5f,  0.0f);
		}
		glEnd();
	}
	glPopMatrix();

	sf::Texture::bind(NULL);
}


void Player::update(double dt){
	float x,y;
	x = cos(m_angle);
	y = sin(m_angle);
	b2Vec2 f(x,y),p;

	b2Vec2 vel;

	if(getPosition().x > 20)
		m_state = 4;

	switch(m_state){
	case 0: // Parat
		m_frame = 0;
		break;
	case 1: // Correr
		
		vel = m_body->GetLinearVelocity();
		m_body->SetLinearVelocity(b2Vec2(20.0f, vel.y));
		if(getPosition().x >= m_jumpPos.x){
			m_state = 2;
			m_body->SetLinearVelocity(b2Vec2(0,vel.y));
		}

		if(getPosition().x > -13.5f){
			m_frame = 4;
		}else{
			if(!m_runAnim){
				m_frame += 1;
				if(m_frame>3){
					m_frame = 2;
					m_runAnim=true;
				}
			}else{
				m_frame-=1;
				if(m_frame<0){
					m_frame = 1;
					m_runAnim=false;
				}
			}
		}

		

		break;
	case 2: // Moment del bot
		m_frame = 7;
		m_body->SetFixedRotation(false);
		f = m_body->GetWorldVector(f);
		f.Normalize();
		f *= m_force;
		p = m_body->GetWorldCenter();
		m_body->ApplyLinearImpulse(f,p);

		m_state = 3;

		break;
	case 3: // En el aire
		m_body->SetAngularVelocity(-2.0f);
		break;
	case 4: // Toquem piso
		break;
	}
}


void Player::beginContact(b2Contact *contact){
	PhysicalObject *me = (PhysicalObject*)contact->GetFixtureA()->GetBody()->GetUserData();
	PhysicalObject *other = (PhysicalObject*)contact->GetFixtureB()->GetBody()->GetUserData();

	if(me != this){ 
		PhysicalObject *temp;
		temp = me;
		me = other;
		other = temp;
	}

	if(other->hasProperty("floor") && m_state == 3){
		m_state = 4;
	}


}

void Player::endContact(b2Contact *contact){
	PhysicalObject *me = (PhysicalObject*)contact->GetFixtureA()->GetBody()->GetUserData();
	PhysicalObject *other = (PhysicalObject*)contact->GetFixtureB()->GetBody()->GetUserData();

	if(me != this){ 
		PhysicalObject *temp;
		temp = me;
		me = other;
		other = temp;
	}

	/*if(other->hasProperty("onewayplatform")){
		m_onFloor = false;
	}*/


}

void Player::PreSolve(b2Contact* contact, const b2Manifold* oldManifold){
	PhysicalObject *me = (PhysicalObject*)contact->GetFixtureA()->GetBody()->GetUserData();
	PhysicalObject *other = (PhysicalObject*)contact->GetFixtureB()->GetBody()->GetUserData();

	if(me != this){ // objectB is the thing you've contacted
		PhysicalObject *temp;
		temp = me;
		me = other;
		other = temp;
	}

	if(other->hasProperty("wall4") && m_gameState->getCurrentLevel() < 4){
		contact->SetEnabled(false);
	}else if(other->hasProperty("window") && m_gameState->m_levelCompleted){
		contact->SetEnabled(false);
	}
}
